<template>
  <div class="page">
    <a-breadcrumb style="margin-bottom:12px">
      <a-breadcrumb-item><router-link to="/">首页</router-link></a-breadcrumb-item>
      <a-breadcrumb-item>热门文章</a-breadcrumb-item>
    </a-breadcrumb>

    <a-card>
      <template #title>热门文章</template>
      <template #extra>
        <div style="display:flex;gap:8px;align-items:center">
          <a-select v-model:value="categoryId" placeholder="分类" allow-clear style="min-width: 140px" @change="onFilterChange">
            <a-select-option v-for="c in categories" :key="c.id" :value="c.id">{{ c.name }}</a-select-option>
          </a-select>
          <a-select v-model:value="tagId" placeholder="标签" allow-clear style="min-width: 140px" @change="onFilterChange">
            <a-select-option v-for="t in tags" :key="t.id" :value="t.id">{{ t.name }}</a-select-option>
          </a-select>
          <a-segmented v-model:value="sinceDays" :options="hotWindowOptions" size="small" @change="onWindowChange" />
          <a-button size="small" @click="exportCSV">导出CSV</a-button>
        </div>
      </template>

      <SkeletonList v-if="loading" :count="8" />
      <EmptyState v-else-if="!loading && (!list || list.length === 0)" text="暂无热门文章" />
      <a-list v-else :grid="{ gutter: 16, xs: 1, sm: 2, md: 3, lg: 4 }" :data-source="list" :locale="{ emptyText: '暂无数据' }">
        <template #renderItem="{ item }">
          <a-list-item>
            <a-card :hoverable="true" class="article-card" @click="goDetail(item.id)">
              <template v-if="item.coverImage" #cover>
                <a-image :src="item.coverImage" :preview="false" />
              </template>
              <a-card-meta :title="item.title">
                <template #description>
                  <div class="summary">{{ item.summary }}</div>
                </template>
              </a-card-meta>
            </a-card>
          </a-list-item>
        </template>
      </a-list>

      <Pager :page-no="pageNo" :page-size="pageSize" :total="total" @update:pageNo="onPageChange" @update:pageSize="onSizeChange" />
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { usePageQuery } from '@/composables/usePageQuery'
import { pageHot, fetchCategories, fetchTags } from '@/api/public/articles'
import type { ArticleListItemVO, PageResponse, CategoryVO, TagVO } from '@/types/api'
import { useRouter, useRoute } from 'vue-router'
import Pager from '@/components/Pager.vue'

const router = useRouter()
const route = useRoute()
const list = ref<ArticleListItemVO[]>([])
const total = ref(0)
const { pageNo, pageSize, categoryId, tagId, sinceDays, pushQuery } = usePageQuery({ pageNo: 1, pageSize: 12, sinceDays: 30 })
const loading = ref(false)
const categories = ref<CategoryVO[]>([])
const tags = ref<TagVO[]>([])
const hotWindowOptions = [
  { label: '7天', value: 7 },
  { label: '30天', value: 30 },
  { label: '全部', value: 0 }
]

async function load() {
  loading.value = true
  try {
    const { data } = await pageHot(pageNo.value, pageSize.value, categoryId.value, tagId.value, sinceDays.value || undefined)
    const payload = data as PageResponse<ArticleListItemVO>
    list.value = payload.records || []
    total.value = payload.total || 0
  } finally {
    loading.value = false
  }
}

function pushQuery() {
  router.replace({ name: 'HotPage', query: {
    p: String(pageNo.value), s: String(pageSize.value), c: categoryId.value, t: tagId.value, d: sinceDays.value
  } as any })
}
function onPageChange(p: number) { pageNo.value = p; pushQuery(); load() }
function onSizeChange(_: number, size: number) { pageSize.value = size; pageNo.value = 1; pushQuery(); load() }
function onWindowChange() { pageNo.value = 1; pushQuery(); load() }
function onFilterChange() { pageNo.value = 1; pushQuery(); load() }
function goDetail(id: number) { router.push({ name: 'ArticleDetail', params: { id } }) }

function escapeCsvCell(v: unknown) {
  const s = (v ?? '').toString()
  if (s.includes('"') || s.includes(',') || s.includes('\n')) {
    return '"' + s.replace(/"/g, '""') + '"'
  }
  return s
}

function exportCSV() {
  const header = ['id','title','categoryId','categoryName','viewCount','likeCount','commentCount','createTime']
  const rows = list.value.map(it => [
    it.id, it.title, it.categoryId ?? '', it.categoryName ?? '', it.viewCount, it.likeCount, it.commentCount, it.createTime
  ])
  const lines = [header, ...rows].map(r => r.map(escapeCsvCell).join(','))
  const csv = '\ufeff' + lines.join('\n')
  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  const c = categoryId.value ? `-c${categoryId.value}` : ''
  const t = tagId.value ? `-t${tagId.value}` : ''
  const d = sinceDays.value != null ? `-d${sinceDays.value}` : ''
  a.download = `hot-articles${c}${t}${d}-p${pageNo.value}-s${pageSize.value}.csv`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

onMounted(async () => {
  const p = Number(route.query.p); if (p > 0) pageNo.value = p
  const s = Number(route.query.s); if (s > 0) pageSize.value = s
  const c = Number(route.query.c); if (c > 0) categoryId.value = c
  const t = Number(route.query.t); if (t > 0) tagId.value = t
  const d = Number(route.query.d); if (d >= 0) sinceDays.value = d
  const [cs, ts] = await Promise.all([fetchCategories(), fetchTags()])
  categories.value = cs.data || []
  tags.value = ts.data || []
  await load()
})
</script>

<style scoped>
.page { max-width: 1200px; margin: 0 auto; padding: 12px; }
.article-card { height: 100%; }
.summary { color: rgba(0,0,0,0.65); margin-top: 8px; display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pager { margin-top: 16px; text-align: center; }
</style>
